package am.NotenProgramm.objects;

public class Subject {
	String name;
	Grade[] grades;
	double average;
	double averageTests;
	double averageOral;
	double oralWeight = 0.1; // value from 0 to 1
	double subjectWeight = 1.0;

	// Constructor without input
	public Subject(String name) {
		this.name = name;
		grades = new Grade[0];
		oralWeight = 0.0;
		subjectWeight = 0.0;
		calculateAverage();
	}

	// Constructor for manual input
	public Subject(String name, Grade[] grades, double oralWeight,
			double subjectWeight) {
		this.name = name;
		this.grades = grades;
		this.oralWeight = oralWeight;
		this.subjectWeight = subjectWeight;
		calculateAverage();
	}

	// Constructor for String with details
	public Subject(String name, Grade[] grades, String stringToFeed) {
		this.name = name;
		this.grades = grades;
		// Split String and Search for Variables
		String[] splitedElements = stringToFeed.split("<,>");
		for (int i = 0; i < splitedElements.length; i++) {
			if (splitedElements[i].startsWith("oralWeight=")) {
				oralWeight = Double.parseDouble(splitedElements[i]
						.substring(11));
			} else if (splitedElements[i].startsWith("subjectWeight=")) {
				subjectWeight = Double.parseDouble(splitedElements[i]
						.substring(14));
			}
		}
		calculateAverage();
	}

	// Calculate Oral, Tests and Overall Averages
	public void calculateAverage() {
		double tmpValTests = 0.0;
		double tmpDivTests = 0.0;
		double tmpValOral = 0.0;
		double tmpDivOral = 0.0;
		for (int i = 0; i < grades.length; i++) {
			// Test if the Grade is Oral, then get the Value and add it
			if (grades[i].isOral()) {
				tmpValOral += grades[i].getGrade() * grades[i].getWeight();
				tmpDivOral += grades[i].getWeight();
			} else {
				tmpValTests += grades[i].getGrade() * grades[i].getWeight();
				tmpDivTests += grades[i].getWeight();
			}
		}
		// Divide the Sum of the Grades by the number of grades
		if(tmpDivTests != 0){
			averageTests = tmpValTests / tmpDivTests;
		} else {
			averageTests = 0.0;
		}
		if(tmpDivOral != 0){
			averageOral = tmpValOral / tmpDivOral;
		} else {
			averageOral = 0.0;
		}
		
		
		if (averageOral == 0.0) {
			average = averageTests;
		} else if (averageTests == 0.0){
			average = averageOral;
		} else {
			average = averageTests * (1.0 - oralWeight) + averageOral* oralWeight;
		}
	}

	// Function to Save Variables in a String which can be saved by
	// DataStream.java
	public String getString() {
		return "subjectData=oralWeight=" + oralWeight + "<,>subjectWeight="
				+ subjectWeight + "<grade>";
	}

	// Add/Remove Grade
	public void addGrade(Grade grade) {
		Grade[] tmpGrades = grades;
		grades = new Grade[tmpGrades.length + 1];
		for (int i = 0; i < tmpGrades.length; i++) {
			grades[i] = tmpGrades[i];
		}
		grades[grades.length - 1] = grade;
	}

	public void removeGrade(int number) {
		Grade[] tmpGrades = grades;
		grades = new Grade[tmpGrades.length - 1];
		for (int i = 0; i < tmpGrades.length; i++) {
			if (i < number) {
				grades[i] = tmpGrades[i];
			} else if (i > number) {
				grades[i - 1] = tmpGrades[i];
			}
		}
	}

	// Getters and Setters
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Grade[] getGrades() {
		return grades;
	}

	public void setGrades(Grade[] grades) {
		this.grades = grades;
	}

	public double getOralWeight() {
		return oralWeight;
	}

	public void setOralWeight(double oralWeight) {
		this.oralWeight = oralWeight;
	}

	public double getSubjectWeight() {
		return subjectWeight;
	}

	public void setSubjectWeight(double subjectWeight) {
		this.subjectWeight = subjectWeight;
	}

	public double getAverage() {
		calculateAverage();
		return average;
	}

	public double getAverageTests() {
		calculateAverage();
		return averageTests;
	}

	public double getAverageOral() {
		calculateAverage();
		return averageOral;
	}
}
